home *** CD-ROM | disk | FTP | other *** search
/ C/C++ Users Group Library 1996 July / C-C++ Users Group Library July 1996.iso / vol_400 / 421_01 / makefrac.cpp < prev    next >
Encoding:
C/C++ Source or Header  |  1994-01-16  |  10.4 KB  |  552 lines

  1. // **************************************************************************
  2.  
  3. #include <graphics.h>
  4. #include <stdlib.h>
  5. #include <stdio.h>
  6. #include <math.h>
  7. #include <conio.h>
  8.  
  9. #include "template.h"
  10. #include "svga256.h"
  11.  
  12. typedef double flyt;
  13. typedef unsigned int word;
  14. typedef unsigned char byte;
  15.  
  16. #define FRAMES  44  // Number of times the resolution is doubled
  17. #define EXT            192    // Size of window, in pixels
  18. #define VIEW    2.5
  19. #define EXTPARTS 6
  20. #define FX2     -1.38138562516074
  21. #define FY2             0.09709670415710
  22. #define POLKADOT -EXT/2
  23.  
  24. #define FILTER  1
  25.  
  26. #define FX2     -1.67470096283140
  27. #define FY2      0.00006950133713
  28.  
  29. #define FX2            -0.82226457050119
  30. #define FY2             0.17599715464079
  31.  
  32. #define LIMIT   10
  33.  
  34. #define LX -1
  35. #define LY 0.5
  36. #define LZ 1
  37.  
  38. #define RAD     50
  39. #define PI 3.1415926535
  40. #define RATIO 1
  41.  
  42. float rgbplussr,rgbfacr=4.4,rgbplussg,rgbfacg=7.8,rgbplussb,rgbfacb=11.3;
  43. int globalblank=0;
  44.  
  45. // DETECTVGA
  46.  
  47. int huge DetectVGA256(void) {return 4;}
  48.  
  49. int data004[10000];
  50. int maxused=0,maxcol=20;
  51.  
  52. word diffno[512],diffnum=0,feil;
  53.  
  54. // GRAFIKK
  55.  
  56. void grafikk(void)
  57. {
  58.     int gd=DETECT, Gm;
  59.     installuserdriver("Svga256",DetectVGA256);
  60.     initgraph(&gd,&Gm,"");
  61.     for (int teller=1; teller<256; teller++)
  62.     {
  63.         setpalette(teller,teller);
  64.  
  65.         flyt r=sin(rgbplussr+teller*rgbfacr*PI/255);
  66.         flyt g=sin(rgbplussg+teller*rgbfacg*PI/255);
  67.         flyt b=sin(rgbplussb+teller*rgbfacb*PI/255);
  68.  
  69.         r=fabs(r)*63;
  70.         g=fabs(g)*63;
  71.         b=fabs(b)*63;
  72.  
  73.         setrgbpalette(teller,r,g,b);
  74.         setcolor(teller);
  75.         line(1000,teller*2,1023,teller*2);
  76.     }
  77. }
  78.  
  79. // WPUTPIXEL
  80.  
  81. void wputpixel(int x,int y,byte color, byte vindu)
  82. {
  83.   if (x>319 || x<0 || y>239 || y<0)
  84.         return;
  85.     putpixel(x+350*(vindu%3),y+100+250*(vindu/3),color);
  86. }
  87.  
  88. // WGETPIXEL
  89.  
  90. byte wgetpixel(int x,int y,byte vindu)
  91. {
  92.     if (x>320 || x<0 || y>240 || y<0)
  93.     return 0;
  94.     return getpixel(x+350*(vindu%3),y+100+(vindu/3)*250);
  95. }
  96.  
  97. // RECTANGLE
  98.  
  99. void wrectangle(int x0,int y0,int x1,int y1,byte color,
  100.   byte vindu,byte pluss=0)
  101. {
  102.   for (int y=y0; y<=y1; y++,color+=pluss)
  103.   for (int x=x0; x<=x1; x++)
  104.     wputpixel(x,y,color,vindu);
  105. }
  106.  
  107. // DIFF
  108.  
  109. void diff(byte w1,byte w2,byte w3)
  110. {
  111.     for (int x=0; x<EXT; x++)
  112.     for (int y=0; y<EXT; y++)
  113.     {
  114.         byte no1=wgetpixel(x,y,w1);
  115.         byte no2=wgetpixel(x,y,w2);
  116.         byte dino=no1-no2;
  117.         if (dino)
  118.         {
  119.             feil++;
  120.             diffno[dino]++;
  121.             putpixel(960l-(diffno[dino]/20),dino+65,40);
  122.             wputpixel(x,y,no2+dino,w1);
  123.             diffnum++;
  124.         }
  125.         wputpixel(x,y,dino,w3);
  126.     }
  127. }
  128.  
  129. // KUGEL
  130.  
  131.  
  132. void kugel(float rad=RAD)
  133. {
  134.     long pix=0,shad=0;
  135.     for (float x=-rad; x<=rad; x++)
  136.     for (float y=-rad; y<=rad; y++)
  137.     if (x*x+y*y<rad*rad)
  138.     {
  139.         pix++;
  140.         float dx=x/rad;
  141.         float dy=y/rad;
  142.         float dz=sqrt(1-dx*dx-dy*dy);
  143.         float ny=(dx*LX)+(dy*LY)+(dz*LZ);
  144.         int shade=0;
  145.         if (ny<=0)
  146.         {
  147.             ny=0;
  148.             shade=1;
  149.         }
  150.         ny+=random(100)/3000.0;
  151.         shad+=shade;
  152.         ny=17*ny+12;
  153.         for (int xx=0; xx<RATIO; xx++)
  154.         for (int yy=0; yy<RATIO; yy++)
  155.             putpixel(x*RATIO+xx+RATIO*rad,y*RATIO+yy+RATIO*rad,ny);
  156.     }
  157.     for (x=-rad; x<=rad; x++)
  158.     for (float y=-rad; y<=rad; y++)
  159.         putpixel(x+500,y+200,getpixel(x+rad,y+rad));
  160.     for (x=-rad; x<=rad; x++)
  161.     for (float y=-rad; y<=rad; y++)
  162.     {
  163.         int fac[]={2,3,2,3,6,3,2,3,2};
  164.         int col=0;
  165.         int teller=0;
  166.         for (int dx=-1; dx<=1; dx++)
  167.         for (int dy=-1; dy<=1; dy++)
  168.             col+=fac[teller++]*getpixel((x+dx)+500,(y+dy)+200);
  169.         if (col<8*26)
  170.             col=0;
  171.         for (int xx=0; xx<3; xx++)
  172.         for (int yy=0; yy<3; yy++)
  173.         if (col)
  174.         {
  175.             putpixel((x+rad)*3+xx,(y+rad)*3+yy,col/26);
  176.             putpixel((x+rad)*3+xx+28,(y+rad)*3+yy+36,col/26);
  177.             putpixel((x+rad)*3+xx+12,(y+rad)*3+yy+84,col/26);
  178.         }
  179.     }
  180.  
  181. }
  182.  
  183. void mult(flyt &x,flyt &y,flyt x2,flyt y2)
  184. {
  185.     flyt nx=x*x2-y*y2;
  186.     y=x*y2+x2*y;
  187.     x=nx;
  188. }
  189.  
  190. // FCOL
  191.  
  192. // Here's where the fractal values are calculated.
  193.  
  194. byte fcolor(flyt x,flyt y)
  195. {
  196.     flyt xx,yy;
  197.     xx=0;
  198.     yy=0;
  199.     int iter=0;
  200.     while(1)
  201.     {
  202.         iter++;
  203.         if (iter>=maxcol)
  204.             return 0;
  205.         mult(xx,yy,xx,yy);
  206.         xx+=x;
  207.         yy+=y;
  208.         if (xx*xx+yy*yy>LIMIT)
  209.             goto done;
  210.     }
  211. done:
  212.     if (iter<maxcol && iter>maxused)
  213.     {
  214.         maxcol=iter+40;
  215.         maxused=iter;
  216.         putpixel(975,iter,200);
  217.     }
  218.     return iter;
  219. }
  220.  
  221. void fract(flyt x,flyt y,flyt width,int vindu=0)
  222. {
  223.     flyt top=y-width;
  224.     flyt left=x-width;
  225.     flyt step=2*width/EXT;
  226.     flyt xx,yy=top;
  227.     for (int tx=0; tx<EXT; tx++)
  228.     {
  229.         xx=left;
  230.         for(int ty=0; ty<EXT; ty++)
  231.         {
  232.             int blank=globalblank;
  233.             for (int rx=-2; rx<=2 && blank; rx++)
  234.             for (int ry=-2; ry<=2 && blank; ry++)
  235.                 blank&=(!wgetpixel(tx+rx,ty+ry,2));
  236.             byte c;
  237.             if (!blank)
  238.                 c=fcolor(xx,yy);
  239.             else
  240.                 c=0;
  241.             wputpixel(tx,ty,c,vindu);
  242.             xx+=step;
  243.         }
  244.         yy+=step;
  245.     }
  246.     wputpixel(POLKADOT,POLKADOT,100,vindu);
  247. }
  248.  
  249. // COPY
  250.  
  251. void copy(int from,int to)
  252. {
  253.     for (int teller=0; teller<EXT; teller++)
  254.     for (int t=0; t<EXT; t++)
  255.         wputpixel(teller,t,wgetpixel(teller,t,from),to);
  256. }
  257.  
  258. // ZOOM
  259.  
  260. void zoom(int from,int to)
  261. {
  262.     for (int x=0; x<EXT/2; x++)
  263.     for (int y=0; y<EXT/2; y++)
  264.     {
  265.         int c=wgetpixel(x+EXT/4,y+EXT/4,from);
  266.         for (int xx=0; xx<2; xx++)
  267.         for (int yy=0; yy<2; yy++)
  268.             wputpixel(x*2+xx,y*2+yy,c,to);
  269.     }
  270. }
  271.  
  272. // PUSHBIT
  273.  
  274. long pushbit(FILE *fp, word bit)
  275. {
  276.     static long len=0;
  277.     static byte data=0,count=0;
  278.     if (bit==54321)
  279.     {
  280.         len=count=0;
  281.     return 0;
  282.     }
  283.     if (bit==43198 && !count)
  284.         return len;
  285. emptyit:
  286.     data<<=1;
  287.     data|=(bit&1);
  288.     count++;
  289.     if (count==8)
  290.     {
  291.         fwrite(&data,1,1,fp);
  292.         len++;
  293.         data=count=0;
  294.     }
  295.     if (bit==43198 && count)
  296.         goto emptyit;
  297.     return len;
  298. }
  299.  
  300. // PUSHMODE
  301.  
  302. void pushmode(byte data,byte len,FILE *fp)
  303. {
  304.     for (int teller=0; teller<len; teller++)
  305.     {
  306.         pushbit(fp,data&1);
  307.         data>>=1;
  308.     }
  309. }
  310.  
  311. // MAKEDATA
  312.  
  313. void makedata(int x,int y,int br, FILE *fp)
  314. {
  315.     if (br>1)
  316.     {
  317.         for (int yy=0; yy<2; yy++)
  318.         for (int xx=0; xx<2; xx++)
  319.         {
  320.             int hit=0;
  321.             for (int scx=0; scx<br/2; scx++)
  322.             for (int scy=0; scy<br/2; scy++)
  323.             {
  324.                 byte col=wgetpixel(x+xx*br/2+scx,y+yy*br/2+scy,3);
  325.                 if (col)
  326.                 {
  327.                     hit=1;
  328.                     goto hitsomething;
  329.                 }
  330.             }
  331. hitsomething:
  332.             if (hit)
  333.             {
  334.                 pushbit(fp,1);
  335.                 makedata(x+xx*br/2,y+yy*br/2,br/2,fp);
  336.             }
  337.             else
  338.                 pushbit(fp,0);
  339.  
  340.         }
  341.     }
  342.     else
  343.     {
  344.         byte col=wgetpixel(x,y,3);
  345.         if (col==1)
  346.         {
  347.             pushbit(fp,1);
  348.             pushbit(fp,1);
  349.         }
  350.         else
  351.         if (col==255)
  352.         {
  353.             pushbit(fp,1);
  354.             pushbit(fp,0);
  355.         }
  356.         else
  357.         {
  358.             pushbit(fp,0);
  359.             if (col<10)
  360.             {
  361.                 pushbit(fp,1);
  362.                 pushmode(col-2,3,fp);
  363.             }
  364.             else
  365.             if (col>247)
  366.             {
  367.                 pushbit(fp,0);
  368.                 pushmode(col-247,3,fp);
  369.             }
  370.             else
  371.             {
  372.                 pushbit(fp,0);
  373.                 pushmode(0,3,fp);
  374.                 pushmode(col,8,fp);
  375.             }
  376.         }
  377.         wputpixel(x,y,40,3);
  378.     }
  379. }
  380.  
  381. // SAVEDIFF
  382.  
  383. void savediff(FILE *fp)
  384. {
  385.     for (int y=0; y<EXTPARTS; y++)
  386.     for (int x=0; x<EXTPARTS; x++)
  387.     {
  388.         makedata(x*(EXT/EXTPARTS),y*(EXT/EXTPARTS),EXT/EXTPARTS,fp);
  389.         pushbit(fp,43198);
  390.     }
  391. }
  392.  
  393. // MAKEFRACDATA
  394.  
  395. void makefracdata(void)
  396. {
  397.     char *text="01";
  398.     FILE *bitdata=fopen("LIGHTC.005","wb");
  399.     FILE *o06=fopen("LIGHTC.007","wb");
  400.     for (int bl=0; bl<255; bl++)
  401.         diffno[bl]=0;
  402.     feil=0;
  403.     flyt initwidth=VIEW;
  404.     for (int teller=0; teller<FRAMES; teller++)
  405.     {
  406.         for (int uu=0; uu<10; uu++)
  407.         for (int ii=0; ii<30; ii++)
  408.             putpixel(ii,uu,0);
  409.         outtextxy(0,0,text);
  410.         text[1]++;
  411.         if (text[1]==58)
  412.         {
  413.             text[0]++;
  414.             text[1]=48;
  415.         }
  416.  
  417.         fract(FX2,FY2,initwidth,0);
  418.         if (!teller)
  419.         {
  420.             FILE *dump=fopen("LIGHTC.006","wb");
  421.             for (int teller=0; teller<EXT; teller++)
  422.             for (int t=0; t<EXT; t++)
  423.             {
  424.                 byte c=wgetpixel(teller,t,0);
  425.                 c^=(teller+t);
  426.                 fwrite(&c,1,1,dump);
  427.             }
  428.             fclose(dump);
  429.         }
  430.         zoom(1,2);
  431.         if (teller)
  432.         {
  433.             globalblank=1;
  434. #if FILTER
  435.             byte spaadd;
  436.             for (int x=0; x<320; x++)
  437.             for (int y=0; y<240; y++)
  438.             {
  439.                 byte here=wgetpixel(x,y,0);
  440.                 if (!here)
  441.                 if ((spaadd=wgetpixel(x,y,2))!=here)
  442.                     if (here!=wgetpixel(x-1,y,0))
  443.                         if (here!=wgetpixel(x+1,y,0))
  444.                             if (here!=wgetpixel(x,y+1,0))
  445.                                 if (here!=wgetpixel(x,y-1,0))
  446.                                     wputpixel(x,y,spaadd,0);
  447.             }
  448. #endif
  449.  
  450.             diff(0,2,3);
  451.             savediff(bitdata);
  452.         }
  453.         initwidth/=2;
  454.         copy(0,1);
  455.         zoom(0,2);
  456.         int len;
  457.         if (teller)
  458.         {
  459.             len=pushbit(bitdata,43198);
  460.             fwrite(&len,1,2,o06);
  461.             pushbit(bitdata,54321);
  462.         }
  463.     }
  464.     fclose(bitdata);
  465.     fclose(o06);
  466. }
  467.  
  468. // MAIN
  469.  
  470. void main(void)
  471. {
  472.     grafikk();
  473.     makefracdata();
  474. }
  475.  
  476. /*
  477.  
  478. VINDUSFORDELING:
  479.  
  480. 0 - SKIKKELIG BILDE
  481. 1 - FORRIGE BILDE
  482. 2 - ZOOM PAA FORRIGE BILDE
  483.  
  484. FORMAT, DATAFILER:
  485. ******************
  486.  
  487. .004
  488. ----
  489.  
  490. * Antall bytes i tilh0rende nedpakkede bilde i 005 (word)
  491.     * Antall direkte kopier som skal foretas fra originalt bilde (word)
  492.         * Peker til originalt bilde (word)
  493.         * Peker til posisjon i nytt bilde (word)
  494.         * Bredde (byte)
  495.         * H0yde (byte)
  496.     * Antall direkte kopier som skal foretas innen det nye bildet, etter at
  497.         finjusteringa er foretatt (word)
  498.         * Peker til nytt bilde (word)
  499.         * Peker til posisjon i nytt bilde (word)
  500.         * Bredde (byte)
  501.         * H0yde (byte)
  502.  
  503. FILE.005
  504. --------
  505.  
  506. * Within each XXxYY block:
  507.     ? x 4    (2)
  508.     ? x 16   (4)
  509.     ? x 64   (8)
  510.     ? x      (16)
  511.     ? x            (32)
  512.     ? x 4096 (64)
  513.  
  514.     The data is then aligned to the next byte after each block
  515.  
  516. .006 Original bmp
  517.  
  518.     The animation is run in this way:
  519.  
  520.     There is always two completed image A and B) stored in memory.
  521.     The actual zooming is simply a matter of making a smooth transition from
  522.     one picture to the other (simple scaling). A third image (C) is gradually
  523.     decompressed in the background. At the moment this is done, the program
  524.     copies the B-pointer to the A-pointer, the C-pointer to the B-pointer and
  525.     resumes decompressing a new picture. (The uneven motion of the zoom is
  526.     caused by a rounding error when combining picture A and B).
  527.  
  528.     The images themselves are compressed like this:
  529.  
  530.     1. Take the center of the last image and scale it to a factor of two.
  531.     2. Subtract this image from the newly rendered one. This gives a heavy
  532.          distribution of -1s, 0s and 1s.
  533.     3. This picture is recursively compressed by subdividing the area into
  534.          smaller and smaller squares, with a 0 indicating an area where no change
  535.          is needed.
  536.     4. At the end of each branch, the color is compressed with variable length
  537.          encoding, using the following scheme:
  538.  
  539.     After every collision:
  540.  
  541.     1 - 1 - 1
  542.             0 - 255
  543.     0 - 1 - 2->9
  544.             0 - 248->254
  545.  
  546.                     A value of 248 -> read next 8 bits.
  547.  
  548.     (I didn't bother implementing Huffman encoding)
  549.  
  550.     All digits are stored low bit first, i.e bit 0-1-2-3-4-5-6-7
  551.  
  552. */